package server

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"

	"github.com/TarsCloud/TarsGo/tars"
	"github.com/gogf/gf/util/gconv"
	"github.com/wzh200x/hyperNexus/hyperNexusErr"
	"github.com/wzh200x/hyperNexus/hyperNexusProtocol/commonProtocol"
	"github.com/wzh200x/hyperNexus/hyperNexusProtocol/interfaceServerProtocol"
	"github.com/wzh200x/interfaceServer/constant"
	"google.golang.org/protobuf/types/known/emptypb"
)

// interfaceServerOperateImp servant implementation
type interfaceServerOperateImp struct {
}

// Init servant init
func (imp *interfaceServerOperateImp) Init() error {
	//initialize servant here:
	//...
	return nil
}

// Destroy servant destroy
func (imp *interfaceServerOperateImp) Destroy() {
	//destroy servant here:
	//...
}

func (imp *interfaceServerOperateImp) MiniGamePlatformLogin(ctx context.Context, input interfaceServerProtocol.LoginRequest) (output interfaceServerProtocol.LoginResponse, err error) {
	//Doing something in your function
	//...
	platform := ServerApp.PlatformHelper.GetPlatform(input.Platform)
	if platform == nil {
		return output, fmt.Errorf("%v: 不支持的平台类型", hyperNexusErr.ErrCode_PlatformNotSupport)
	}
	output, err = platform.Login(ctx, &input)
	if err != nil {
		return output, fmt.Errorf("%v:登录失败, platform_ret:%s", hyperNexusErr.ErrCode_PlatformLoginFailed, err.Error())
	}
	return output, nil
}

func (imp *interfaceServerOperateImp) ByteJumpAdOauth(ctx context.Context, input interfaceServerProtocol.AdOauthInfo) (output emptypb.Empty, err error) {
	// 构建请求参数
	params := map[string]interface{}{
		"app_id":    input.AppId,
		"secret":    input.Secret,
		"auth_code": input.AuthCode,
	}
	// 发送POST请求
	// 将参数转换为JSON
	jsonData, err := json.Marshal(params)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("参数序列化失败: %v\n", err)
		return
	}
	resp, err := http.Post("https://api.oceanengine.com/open_api/oauth2/access_token/",
		"application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("抖音广告认证请求失败: %v\n", err)
		return
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("读取抖音广告认证响应失败: %v\n", err)
		return
	}
	// 解析响应体
	var response map[string]interface{}
	err = json.Unmarshal(body, &response)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("响应体解析失败: %v\n", err)
		return
	}
	// 检查响应状态
	if gconv.String(response["code"]) != "0" {
		tars.GetLogger("bytejump_ad").Errorf("抖音广告认证失败: %v\n", response)
		tars.GetLogger("bytejump_ad").Errorf("抖音广告认证内容: %v\n", input)
		return
	}
	// 更新 token信息到数据库
	var tokenInfo map[string]interface{}
	tokenInfo = make(map[string]interface{})
	if data, ok := response["data"].(map[string]interface{}); ok {
		tokenInfo["app_id"] = input.AppId
		tokenInfo["app_secret"] = input.Secret
		tokenInfo["access_token"] = data["access_token"]
		tokenInfo["refresh_token"] = data["refresh_token"]
		tokenInfo["expires_in"] = data["expires_in"]
		tokenInfo["refresh_token_expires_in"] = data["refresh_token_expires_in"]
		tokenInfo["refresh_time"] = time.Now().Unix()
	}
	// 解析成字符串
	tokenInfoStr, err := json.Marshal(tokenInfo)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("tokenInfo 序列化失败: %v\n", err)
		return
	}
	dbAgentClient := ServerApp.DbAgentServerClient.GetClientProxy()
	cacheKey := constant.CacheKeyByteJumpAdToken + "_" + input.AppId
	queryPlatform := &commonProtocol.PlatformQuery{
		PlatformKeys: []string{cacheKey},
	}
	re, err := dbAgentClient.QueryPlatform(*queryPlatform)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("QueryPlatform 失败: %v\n", err)
		return
	}
	// 判断结果是否为空
	if len(re.Platforms) == 0 {
		// 创建数据
		createPlatform := &commonProtocol.Platform{
			PlatformKey:   cacheKey,
			PlatformValue: string(tokenInfoStr),
		}
		_, err = dbAgentClient.CreatePlatform(*createPlatform)
		if err != nil {
			tars.GetLogger("bytejump_ad").Errorf("CreatePlatform 失败: %v\n", err)
		}
	} else {
		// 更新数据
		updatePlatform := &commonProtocol.Platform{
			PlatformKey:   cacheKey,
			PlatformValue: string(tokenInfoStr),
		}
		_, err = dbAgentClient.UpdatePlatform(*updatePlatform)
		if err != nil {
			tars.GetLogger("bytejump_ad").Errorf("UpdatePlatform 失败: %v\n", err)
		}
	}

	return output, nil
}

func (imp *interfaceServerOperateImp) ByteJumpAdOauthRefresh(ctx context.Context, input interfaceServerProtocol.AdOauthRefreshInfo) (output emptypb.Empty, err error) {
	// 构建请求参数
	params := map[string]interface{}{
		"app_id":        input.AppId,
		"secret":        input.Secret,
		"refresh_token": input.RefreshToken,
	}
	// 发送POST请求
	// 将参数转换为JSON
	jsonData, err := json.Marshal(params)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("参数序列化失败: %v\n", err)
		return
	}
	resp, err := http.Post("https://api.oceanengine.com/open_api/oauth2/refresh_token/",
		"application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("抖音广告刷新token请求失败: %v\n", err)
		return
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("读取抖音广告刷新token响应失败: %v\n", err)
		return
	}
	// 解析响应体
	var response map[string]interface{}
	err = json.Unmarshal(body, &response)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("读取抖音广告刷新token响应解析失败: %v\n", err)
		return
	}
	// 检查响应状态
	if gconv.String(response["code"]) != "0" {
		tars.GetLogger("bytejump_ad").Errorf("抖音广告刷新token失败: %v\n", response)
		tars.GetLogger("bytejump_ad").Errorf("抖音广告刷新token内容: %v\n", input)
		return
	}
	// 更新 token信息到数据库
	var tokenInfo map[string]interface{}
	tokenInfo = make(map[string]interface{})
	if data, ok := response["data"].(map[string]interface{}); ok {
		tokenInfo["app_id"] = input.AppId
		tokenInfo["app_secret"] = input.Secret
		tokenInfo["access_token"] = data["access_token"]
		tokenInfo["refresh_token"] = data["refresh_token"]
		tokenInfo["expires_in"] = data["expires_in"]
		tokenInfo["refresh_token_expires_in"] = data["refresh_token_expires_in"]
		tokenInfo["refresh_time"] = time.Now().Unix()
	}
	// 解析成字符串
	tokenInfoStr, err := json.Marshal(tokenInfo)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("tokenInfo 序列化失败: %v\n", err)
		return
	}
	dbAgentClient := ServerApp.DbAgentServerClient.GetClientProxy()
	cacheKey := constant.CacheKeyByteJumpAdToken + "_" + input.AppId
	queryPlatform := &commonProtocol.PlatformQuery{
		PlatformKeys: []string{cacheKey},
	}
	re, err := dbAgentClient.QueryPlatform(*queryPlatform)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("QueryPlatform 失败: %v\n", err)
		return
	}
	// 判断结果是否为空
	if len(re.Platforms) == 0 {
		// 创建数据
		createPlatform := &commonProtocol.Platform{
			PlatformKey:   cacheKey,
			PlatformValue: string(tokenInfoStr),
		}
		_, err = dbAgentClient.CreatePlatform(*createPlatform)
		if err != nil {
			tars.GetLogger("bytejump_ad").Errorf("CreatePlatform 失败: %v\n", err)
		}
	} else {
		// 更新数据
		updatePlatform := &commonProtocol.Platform{
			PlatformKey:   cacheKey,
			PlatformValue: string(tokenInfoStr),
		}
		_, err = dbAgentClient.UpdatePlatform(*updatePlatform)
		if err != nil {
			tars.GetLogger("bytejump_ad").Errorf("UpdatePlatform 失败: %v\n", err)
		}
	}

	return output, nil
}

func (imp *interfaceServerOperateImp) ByteJumpAdOauthQuery(ctx context.Context, input interfaceServerProtocol.AdOauthQueryInfo) (output interfaceServerProtocol.AdOauthQueryResponse, err error) {
	// 从数据库查询 token信息
	dbAgentClient := ServerApp.DbAgentServerClient.GetClientProxy()
	cacheKey := constant.CacheKeyByteJumpAdToken + "_" + input.AppId
	queryPlatform := &commonProtocol.PlatformQuery{
		PlatformKeys: []string{cacheKey},
	}
	re, err := dbAgentClient.QueryPlatform(*queryPlatform)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("QueryPlatform 失败: %v\n", err)
		return output, err
	}
	// 判断结果是否为空
	if len(re.Platforms) == 0 {
		return output, err
	}
	// 解析 token信息
	var tokenInfo map[string]interface{}
	err = json.Unmarshal([]byte(re.Platforms[0].PlatformValue), &tokenInfo)
	if err != nil {
		tars.GetLogger("bytejump_ad").Errorf("tokenInfo 解析失败: %v\n", err)
		return output, err
	}
	// 构建返回参数
	output.AppId = input.AppId
	output.Secret = gconv.String(tokenInfo["app_secret"])
	output.AccessToken = gconv.String(tokenInfo["access_token"])
	output.RefreshToken = gconv.String(tokenInfo["refresh_token"])
	output.Expires = gconv.Int64(tokenInfo["expires_in"])
	output.ExpiresRefresh = gconv.Int64(tokenInfo["refresh_token_expires_in"])
	output.RefreshTime = gconv.Int64(tokenInfo["refresh_time"])
	return output, nil
}
